package com.ecjtu.stadiumre_servations.config;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ecjtu.stadiumre_servations.entity.domain.Booking;
import com.ecjtu.stadiumre_servations.entity.domain.GroupActivity;
import com.ecjtu.stadiumre_servations.entity.domain.GroupMember;
import com.ecjtu.stadiumre_servations.entity.domain.GroupRecord;
import com.ecjtu.stadiumre_servations.mapper.*;
import com.ecjtu.stadiumre_servations.response.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

// 判段时间冲突
@Component
public class TimeConflictChecker {

    @Autowired
    private GroupMemberMapper groupMemberMapper;

    @Autowired
    private GroupRecordMapper groupRecordMapper;

    @Autowired
    private GroupActivityMapper groupActivityMapper;

    @Autowired
    private BookingMapper bookingMapper;

    @Autowired
    private VenueMapper venueMapper;

    /**
     * 根据成员ID检查用户在对应时间段是否存在时间冲突
     */
    public boolean checkTimeConflictById(String memberId) {
        // 1. 查询成员记录
        GroupMember member = groupMemberMapper.selectById(memberId);
        if (member == null) {
            return false;
        }

        // 2. 查询拼团记录
        GroupRecord groupRecord = groupRecordMapper.selectById(member.getGroupRecordId());
        if (groupRecord == null) {
            return false;
        }

        // 3. 查询活动信息
        GroupActivity activity = groupActivityMapper.selectById(groupRecord.getActivityId());
        if (activity == null) {
            return false;
        }

        // 4. 获取活动报名时间范围和场馆ID
        LocalDateTime activitySignupStartTime = activity.getActivityStartTime();
        LocalDateTime activitySignupEndTime = activity.getActivityEndTime();
        String venueId = activity.getActivityVenueId();

//        // 5. 获取拼团预约场地的时间范围
//        LocalDateTime bookingStartTime = groupRecord.getStartTime();
//        LocalDateTime bookingEndTime = groupRecord.getEndTime();


        // 5. 获取拼团预约场地的时间范围
        LocalDateTime bookingStartTime = activity.getActivityStartTime();
        LocalDateTime bookingEndTime = activity.getActivityEndTime();
        // 6. 检查用户在该时间段是否已有拼团冲突
        boolean hasGroupConflict = checkGroupConflict(
                member.getUserId(),
                memberId, // 排除当前拼团
                bookingStartTime,
                bookingEndTime
        );

        if (hasGroupConflict) {
            return false;
        }

        // 7. 检查用户在该时间段是否已有场地预约冲突
        boolean hasBookingConflict = checkBookingConflict(
                member.getUserId(),
                bookingStartTime,
                bookingEndTime
        );

        if (hasBookingConflict) {
            return false;
        }

        // 8. 检查同一场馆在该时间段是否已有其他拼团或预约
        boolean hasVenueConflict = checkVenueConflict(
                venueId,
                memberId, // 排除当前拼团
                bookingStartTime,
                bookingEndTime
        );

        if (hasVenueConflict) {
            return false;
        }

        // 9. 检查活动报名时间是否合法
        if (bookingStartTime.isBefore(activitySignupStartTime) ||
                bookingEndTime.isAfter(activitySignupEndTime)) {
            return false;
        }

        // 10. 无冲突
        return true;
    }

    /**
     * 检查用户在指定时间段是否已有其他拼团活动
     */
    public boolean checkGroupConflict(String userId, String excludeMemberId,
                                      LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<GroupMember> queryWrapper = Wrappers.<GroupMember>lambdaQuery()
                .eq(GroupMember::getUserId, userId)
                .eq(GroupMember::getPayStatus, " 已支付") // 已支付
                .ne(StringUtils.isNotBlank(excludeMemberId), GroupMember::getMemberId, excludeMemberId);

        List<GroupMember> memberList = groupMemberMapper.selectList(queryWrapper);

//        for (GroupMember member : memberList) {
//            GroupRecord record = groupRecordMapper.selectById(member.getGroupRecordId());
//            if (record != null && record.getStartTime() != null && record.getEndTime() != null) {
//                // 检查预约场地的时间冲突
//                if (timeRangeOverlap(
//                        record.getStartTime(), record.getEndTime(),
//                        startTime, endTime
//                )) {
//                    return true; // 存在时间冲突
//                }
//            }
//        }
        for (GroupMember member : memberList) {
            GroupRecord record = groupRecordMapper.selectById(member.getGroupRecordId());
            GroupActivity activity = groupActivityMapper.selectById(record.getActivityId());
            if (activity != null && activity.getActivityStartTime() != null && activity.getActivityEndTime() != null) {
                // 检查预约场地的时间冲突
                if (timeRangeOverlap(
                        activity.getActivityStartTime(),  activity.getActivityEndTime(),
                        startTime, endTime
                )) {
                    return true; // 存在时间冲突
                }
            }
        }
        return false;
    }

    /**
     * 检查用户在指定时间段是否已有场地预约
     */
    public boolean checkBookingConflict(String userId,
                                        LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<Booking> queryWrapper = Wrappers.<Booking>lambdaQuery()
                .eq(Booking::getStudentId, userId)
                .in(Booking::getBookingStatus, "待使用", "已使用") // 待使用、已使用
                .and(wrapper -> wrapper
                        .or(q -> q.ge(Booking::getBookingStartTime, startTime)
                                .lt(Booking::getBookingStartTime, endTime))
                        .or(q -> q.le(Booking::getBookingEndTime, endTime)
                                .gt(Booking::getBookingEndTime, startTime))
                        .or(q -> q.le(Booking::getBookingStartTime, startTime)
                                .ge(Booking::getBookingEndTime, endTime))
                );

        List<Booking> bookingList = bookingMapper.selectList(queryWrapper);
        return !bookingList.isEmpty();
    }

    /**
     * 检查同一场馆在指定时间段是否已有其他拼团或预约
     */
    public boolean checkVenueConflict(String venueId, String excludeMemberId,
                                      LocalDateTime startTime, LocalDateTime endTime) {
        // 检查同一场馆的其他拼团活动
        boolean hasGroupVenueConflict = checkGroupVenueConflict(
                venueId, excludeMemberId, startTime, endTime
        );

        if (hasGroupVenueConflict) {
            return true;
        }

        // 检查同一场馆的其他场地预约
        boolean hasBookingVenueConflict = checkBookingVenueConflict(
                venueId, startTime, endTime
        );

        return hasBookingVenueConflict;
    }

    /**
     * 检查同一场馆在指定时间段是否已有其他拼团活动
     */
    public boolean checkGroupVenueConflict(String venueId, String excludeMemberId,
                                           LocalDateTime startTime, LocalDateTime endTime) {
        // 1. 获取当前拼团记录ID（如果存在）
        String currentGroupRecordId = null;
        if (StringUtils.isNotBlank(excludeMemberId)) {
            GroupMember currentMember = groupMemberMapper.selectById(excludeMemberId);
            if (currentMember != null) {
                currentGroupRecordId = currentMember.getGroupRecordId();
            }
        }

        // 2. 查询同一场馆的拼团活动
        LambdaQueryWrapper<GroupActivity> activityQuery = Wrappers.<GroupActivity>lambdaQuery()
                .eq(GroupActivity::getActivityVenueId, venueId)
                .in(GroupActivity::getActivityStatus, "未开始", "进行中"); // 未开始或进行中

        List<GroupActivity> activities = groupActivityMapper.selectList(activityQuery);

        // 3. 检查每个活动下的拼团记录
        for (GroupActivity activity : activities) {
            LambdaQueryWrapper<GroupRecord> recordQuery = Wrappers.<GroupRecord>lambdaQuery()
                    .eq(GroupRecord::getActivityId, activity.getActivityId())
                    .in(GroupRecord::getRecordStatus, "拼团中", "已成团") // 拼团中或已成团
                    .isNotNull(GroupRecord::getStartTime)
                    .isNotNull(GroupRecord::getEndTime)
                    .and(wrapper -> wrapper
                            .or(q -> q.ge(GroupRecord::getStartTime, startTime)
                                    .lt(GroupRecord::getStartTime, endTime))
                            .or(q -> q.le(GroupRecord::getEndTime, endTime)
                                    .gt(GroupRecord::getEndTime, startTime))
                            .or(q -> q.le(GroupRecord::getStartTime, startTime)
                                    .ge(GroupRecord::getEndTime, endTime))
                    );

            // 排除当前拼团记录
            if (currentGroupRecordId != null) {
                recordQuery.ne(GroupRecord::getRecordId, currentGroupRecordId);
            }

            List<GroupRecord> records = groupRecordMapper.selectList(recordQuery);
            if (!records.isEmpty()) {
                return true; // 存在场馆冲突
            }
        }

        return false;
    }

    /**
     * 检查同一场馆在指定时间段是否已有场地预约
     */
    public boolean checkBookingVenueConflict(String venueId,
                                             LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<Booking> queryWrapper = Wrappers.<Booking>lambdaQuery()
                .eq(Booking::getVenueId, venueId)
                .in(Booking::getBookingStatus, "待使用", "已使用") // 待使用、已使用
                .and(wrapper -> wrapper
                        .or(q -> q.ge(Booking::getBookingStartTime, startTime)
                                .lt(Booking::getBookingStartTime, endTime))
                        .or(q -> q.le(Booking::getBookingEndTime, endTime)
                                .gt(Booking::getBookingEndTime, startTime))
                        .or(q -> q.le(Booking::getBookingStartTime, startTime)
                                .ge(Booking::getBookingEndTime, endTime))
                );

        List<Booking> bookingList = bookingMapper.selectList(queryWrapper);
        return !bookingList.isEmpty();
    }

    /**
     * 检查两个时间范围是否重叠
     */
    public boolean timeRangeOverlap(LocalDateTime start1, LocalDateTime end1,
                                     LocalDateTime start2, LocalDateTime end2) {
        return start1.isBefore(end2) && end1.isAfter(start2);
    }
}